home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / util / dres.1 < prev    next >
Text File  |  1988-10-25  |  52KB  |  2,217 lines

  1. Path: xanth!nic.MR.NET!umn-d-ub!rutgers!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i016:  dres - an object-oriented resource library, Part01/03
  5. Message-ID: <9821@swan.ulowell.edu>
  6. Date: 25 Oct 88 00:53:31 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2206
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 16
  13. Archive-name: util/dres.1
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    src/ipc.c
  20. #    src/misc.c
  21. #    src/newres.c
  22. #    src/mem.asm
  23. #    util/gtd.c
  24. #    util/testipc.c
  25. #    util/test.c
  26. #    util/qtest.c
  27. #    util/testarg.c
  28. #    util/x.c
  29. #
  30. if `test ! -d src`
  31. then
  32.   mkdir src
  33.   echo "mkdir src"
  34. fi
  35. if `test ! -s src/ipc.c`
  36. then
  37. echo "writing src/ipc.c"
  38. cat > src/ipc.c << '\Rogue\Monster\'
  39.  
  40. /*
  41.  *  IPC.C   25 September 1988
  42.  *
  43.  *  NOTE!   the BSS segment is not initialized to 0.
  44.  */
  45.  
  46. #include <local/typedefs.h>
  47. #include <local/ipc.h>
  48.  
  49. extern EXECBASE *SysBase;
  50.  
  51. static long  IPCLock[2] = { 0, 0 };
  52. static MLIST IPCList = { (MNODE *)&IPCList.mlh_Tail, NULL, (MNODE *)&IPCList.mlh_Head };
  53.  
  54. extern void *FindName();
  55. extern IPCMSG *lSendIPC2();
  56. extern char *CCall();
  57. extern APTR Duplicate();
  58.  
  59. /*
  60.  *  Three-pass command parser.
  61.  *  (1) Determine # of arguments and allocate argv array, resolve variables
  62.  *  (2) Determine length of each argument and allocate entries in the array
  63.  *  (3) Fill entries in the array
  64.  *
  65.  *  On return, an filled ARGV array will be returned.  To free the argv
  66.  *  array and elements, call FreeParseCmd(argv).  Individual argv[]
  67.  *  entries may be modified, including stuffing different pointers in,
  68.  *  without effecting FreeParseCmd().  Note that offset -1 in each entry
  69.  *  contains a status byte, currently only bit 0 (was quoted) is used.
  70.  */
  71.  
  72. lParseCmd(buf, pav, varget, varfree, error, reserved)
  73. char *buf;
  74. char ***pav;
  75. char *((*varget)());
  76. char *((*varfree)());
  77. long *error;
  78. {
  79.     short numac;        /*    # of argv entries    */
  80.     char **av = NULL;        /*    argv array        */
  81.     long *arglen = NULL;    /*    array of entry lengths    */
  82.     MLIST VList;        /*    Hold $variable contents */
  83.     char *endstrvar();      /*  extracts variable name  */
  84.     short ttllen = 0;        /*    sum of lengths of entries   */
  85.  
  86.     NewList(&VList);
  87.     *error = 0;
  88.  
  89.     /*
  90.      *    PASS1, determine # of arguments and retrieve variables
  91.      */
  92.  
  93.     {
  94.     register char *ptr;
  95.     register short ac = 0;
  96.     register short quo = 0;
  97.  
  98.     for (ptr = buf; *ptr == ' ' || *ptr == 9; ++ptr);
  99.     for (; *ptr; ++ptr) {
  100.         switch(*ptr) {
  101.         case '(':
  102.         ++quo;
  103.         break;
  104.         case ')':
  105.         --quo;
  106.         break;
  107.         case '\\':
  108.         case '^':
  109.         if (ptr[1])
  110.             ++ptr;
  111.         break;
  112.         case ' ':
  113.         case 9:
  114.         if (!quo) {
  115.             while (*ptr == ' ' || *ptr == 9)
  116.             ++ptr;
  117.             if (*ptr)
  118.             ++ac;
  119.             --ptr;
  120.         }
  121.         break;
  122.         case '$':
  123.         {
  124.             short len;
  125.             char tmp[64];
  126.             char *str;
  127.             MNODE *vl;
  128.  
  129.             ++ptr;
  130.             str = endstrvar(ptr, &len);
  131.             if (*ptr == '(')
  132.             ++ptr;
  133.             BMov(ptr, tmp, len);
  134.             tmp[len] = 0;
  135.             if (varget && (ptr = (char *)CCall(varget, tmp))) {
  136.             vl = AllocMem(8 + strlen(ptr) + 1, MEMF_PUBLIC);
  137.             if (!vl) {
  138.                 *error = (PERR_NOMEM << 16) | (ptr - buf);
  139.                 goto fail;
  140.             }
  141.             strcpy(vl+1, ptr);
  142.             if (varfree)
  143.                 CCall(varfree, ptr);
  144.             } else {
  145.             *error = (PERR_NOVAR << 16) | (ptr - buf);
  146.             goto fail;
  147.             }
  148.             AddTail(&VList, vl);
  149.             ptr = str - 1;
  150.         }
  151.         break;
  152.         }
  153.     }
  154.     ++ac;
  155.     numac = ac;
  156.     }
  157.  
  158.     /*
  159.      *    av[-1]    = master string pointer (see below)
  160.      *    av[-2]    = sizeof av array
  161.      *    av[ac]    = NULL
  162.      *
  163.      *    Pass 2, allocate argv array and storage for the lengths of each
  164.      *        entry.    Determine the length of each entry.
  165.      */
  166.  
  167.     av = AllocMem(sizeof(char *) * (numac + 3), MEMF_PUBLIC);
  168.     if (!av) {
  169.     *error = (PERR_NOMEM << 16);
  170.     goto fail;
  171.     }
  172.     av += 2;
  173.     av[-2] = (char *)(sizeof(char *) * (numac + 3));
  174.     arglen = AllocMem(sizeof(long) * numac, MEMF_PUBLIC);
  175.     if (!arglen) {
  176.     *error = (PERR_NOMEM << 16);
  177.     goto fail;
  178.     }
  179.  
  180.     {
  181.     register char *ptr;
  182.     register short ac = 0;
  183.     register short quo = 0;
  184.     register short len = 0;
  185.  
  186.     for (ptr = buf; *ptr == ' ' || *ptr == 9; ++ptr);
  187.     for (; *ptr; ++ptr) {
  188.         switch(*ptr) {
  189.         case '(':
  190.         ++quo;
  191.         if (quo != 1)
  192.             ++len;
  193.         break;
  194.         case ')':
  195.         --quo;
  196.         if (quo)
  197.             ++len;
  198.         break;
  199.         case '\\':
  200.         case '^':
  201.         if (ptr[1]) {
  202.             ++ptr;
  203.             ++len;
  204.         }
  205.         break;
  206.         case ' ':
  207.         case 9:
  208.         if (!quo) {
  209.             while (*ptr == ' ' || *ptr == 9)
  210.             ++ptr;
  211.             if (*ptr) {
  212.             arglen[ac] = len;
  213.             ttllen += len + 2;
  214.             ++ac;
  215.             len = 0;
  216.             }
  217.             --ptr;
  218.         } else {
  219.             ++len;
  220.         }
  221.         break;
  222.         case '$':
  223.         {
  224.             register MNODE *node = RemHead(&VList);
  225.             if (node) {
  226.             len += strlen(node+1);
  227.             AddTail(&VList, node);
  228.             }
  229.             ptr = endstrvar(ptr + 1, NULL) - 1;
  230.         }
  231.         break;
  232.         case '\n':
  233.         break;
  234.         default:
  235.         ++len;
  236.         break;
  237.         }
  238.     }
  239.     arglen[ac] = len;
  240.     ttllen += len + 2;        /* 1 byte status & 1 byte separator */
  241.     ++ac;
  242.     }
  243.     {                    /* allocate space for entries */
  244.     register short i;
  245.     register char *mem = AllocMem(4+ttllen, MEMF_PUBLIC);
  246.     register char *ptr = mem + 4;
  247.  
  248.     if (!mem) {
  249.         *error = (PERR_NOMEM << 16);
  250.         goto fail;
  251.     }
  252.  
  253.     *(long *)mem = 4 + ttllen;
  254.     for (i = 0; i < numac; ++i) {
  255.         *ptr++ = 0;         /*  status byte */
  256.         av[i] = ptr;
  257.         ptr[arglen[i]] = 0;
  258.         ptr += arglen[i] + 1;
  259.     }
  260.     av[-1] = mem;
  261.     }
  262.     {
  263.     register char *ptr;
  264.     register char *avs = av[0];
  265.     register short ac = 0;
  266.     short quo = 0;
  267.  
  268.     for (ptr = buf; *ptr == ' ' || *ptr == 9; ++ptr);
  269.     for (; *ptr; ++ptr) {
  270.         switch(*ptr) {
  271.         case '\\':
  272.         if (ptr[1])
  273.             *avs++ = *++ptr;
  274.         break;
  275.         case '^':
  276.         if (ptr[1])
  277.             *avs++ = *++ptr & 0x1F;
  278.         break;
  279.         case '(':
  280.         ++quo;
  281.         if (quo != 1)
  282.             *avs++ = '(';
  283.         else if (avs == av[ac])     /*  quoted argument */
  284.             avs[-1] = 1;
  285.         break;
  286.         case ')':
  287.         --quo;
  288.         if (quo) {
  289.             *avs++ = ')';
  290.             break;
  291.         }   /* fall through */
  292.         case ' ':
  293.         case 9:
  294.         if (!quo) {
  295.             ++ptr;
  296.             while (*ptr == ' ' || *ptr == 9)
  297.             ++ptr;
  298.             if (*ptr) {
  299.             *avs = 0;
  300.             avs = av[++ac];
  301.             }
  302.             --ptr;
  303.         } else {
  304.             *avs++ = *ptr;
  305.         }
  306.         break;
  307.         case '$':
  308.         {
  309.             register MNODE *node = RemHead(&VList);
  310.             if (node) {
  311.             strcpy(avs, node + 1);
  312.             avs += strlen(avs);
  313.             FreeMem(node, 8 + strlen(node+1) + 1);
  314.             }
  315.             ptr = endstrvar(ptr + 1, NULL) - 1;
  316.         }
  317.         break;
  318.         case '\n':
  319.         break;
  320.         default:
  321.         *avs++ = *ptr;
  322.         break;
  323.         }
  324.     }
  325.     *avs = 0;
  326.     ++ac;
  327.     }
  328.     FreeMem(arglen, sizeof(long) * numac);
  329.     *pav = av;
  330.     av[numac] = NULL;
  331.     return(numac);
  332.  
  333. fail:
  334.     {
  335.     register MNODE *node;
  336.  
  337.     if (arglen)
  338.         FreeMem(arglen, sizeof(long) * numac);
  339.     if (av)
  340.         FreeMem(av - 2, (long)av[-2]);
  341.     while (node = RemHead(&VList))
  342.         FreeMem(node, 8 + strlen(node+1) + 1);
  343.     }
  344.     *pav = NULL;
  345.     return(0);
  346. }
  347.  
  348. lFreeParseCmd(av)
  349. char **av;
  350. {
  351.     FreeMem(av[-1], *(long *)av[-1]);
  352.     FreeMem(av - 2, (long)av[-2]);
  353. }
  354.  
  355. char *
  356. endstrvar(ptr, plen)
  357. short *plen;
  358. register char *ptr;
  359. {
  360.     register short len = 0;
  361.     if (*ptr == '(') {
  362.     ++ptr;
  363.     while (*ptr && *ptr != ')') {
  364.         ++ptr;
  365.         ++len;
  366.     }
  367.     if (*ptr == ')')
  368.         ++ptr;
  369.     } else {
  370.     while ((*ptr >= 'a' && *ptr <= 'z') ||
  371.            (*ptr >= 'A' && *ptr <= 'Z') ||
  372.            (*ptr >= '0' && *ptr <= '9') ||
  373.            (*ptr == '_')) {
  374.         ++len;
  375.         ++ptr;
  376.     }
  377.     }
  378.     if (len > 62)
  379.     len = 62;
  380.     if (plen)
  381.     *plen = len;
  382.     return(ptr);
  383. }
  384.  
  385. IPCPORT *
  386. lOpenIPC(name, flags)
  387. char *name;
  388. {
  389.     register IPCPORT *port;
  390.     register char *ptr;
  391.  
  392.     port = AllocMem(sizeof(IPCPORT), MEMF_PUBLIC|MEMF_CLEAR);
  393.     if (!port)
  394.     goto fail;
  395.     ptr = AllocMem(strlen(name)+1, MEMF_PUBLIC);
  396.     if (!ptr)
  397.     goto fail;
  398.     strcpy(ptr, name);
  399.     port->Flags = flags;
  400.     port->Port.mp_Node.ln_Type = NT_MSGPORT;
  401.     port->Port.mp_Node.ln_Name = ptr;
  402.     port->Port.mp_Flags = PA_SIGNAL;
  403.     port->Port.mp_SigBit = AllocSignal(-1);
  404.     port->Port.mp_SigTask = FindTask(NULL);
  405.     NewList(&port->Port.mp_MsgList);
  406.  
  407.     LockAddr(IPCLock);
  408.     Insert(&IPCList, port, FindName(&IPCList, name));
  409.     UnLockAddr(IPCLock);
  410.     return(port);
  411. fail:
  412.     if (port) {
  413.     FreeMem(port, sizeof(IPCPORT));
  414.     if (ptr)
  415.         FreeMem(ptr, strlen(ptr)+1);
  416.     }
  417.     return(NULL);
  418. }
  419.  
  420. void
  421. lCloseIPC(port)
  422. register IPCPORT *port;
  423. {
  424.     register IPCMSG *msg;
  425.  
  426.     LockAddr(IPCLock);              /*  remove port (no new messages)   */
  427.     Remove(port);
  428.     UnLockAddr(IPCLock);
  429.     while (msg = GetMsg(port))      /*  reply to pending msgs w/error   */
  430.     ReplyIPC(msg, NULL, 0, IF_NOTFND);
  431.     FreeMem(port->Port.mp_Node.ln_Name, strlen(port->Port.mp_Node.ln_Name)+1);
  432.     if (port->Port.mp_Flags == PA_SIGNAL)
  433.     FreeSignal(port->Port.mp_SigBit);
  434.     FreeMem(port, sizeof(IPCPORT));
  435. }
  436.  
  437. /*
  438.  *  msg = SendIPC(appname, buf, len, flags)
  439.  */
  440.  
  441. IPCMSG *
  442. lSendIPC(name, buf, len, flags)
  443. char *name;
  444. APTR buf;
  445. register long len, flags;
  446. {
  447.     register IPCMSG *msg;
  448.     register PORT *rport;
  449.  
  450.     msg = AllocMem(sizeof(IPCMSG)+sizeof(PORT), MEMF_PUBLIC|MEMF_CLEAR);
  451.     if (msg == NULL)
  452.     return(NULL);
  453.     flags |= IF_ALLOCMSG;        /*    auto-deallocate later on    */
  454.     rport = (PORT *)(msg + 1);
  455.     if (buf && !(flags & IF_NOCOPY) && !(flags & IF_ALLOC)) {
  456.     if (!(buf = Duplicate(buf, len))) {
  457.         FreeMem(msg, sizeof(IPCMSG)+sizeof(PORT));
  458.         return(NULL);
  459.     }
  460.     flags |= IF_ALLOC;
  461.     }
  462.     rport->mp_Node.ln_Type = NT_MSGPORT;
  463.     rport->mp_Flags = PA_SIGNAL;
  464.     rport->mp_SigBit = 4;
  465.     rport->mp_SigTask = SysBase->ThisTask;
  466.     NewList(&rport->mp_MsgList);
  467.  
  468.     msg->Msg.mn_ReplyPort = rport;
  469.     msg->Msg.mn_Length = sizeof(IPCMSG) + sizeof(PORT);
  470.     msg->TBuf = buf;
  471.     msg->TLen = len;
  472.     msg->TFlags = flags;
  473.     return(lSendIPC2(name, msg));
  474. }
  475.  
  476. IPCMSG *
  477. lSendIPC2(name, msg)
  478. char *name;
  479. register IPCMSG *msg;
  480. {
  481.     register IPCPORT *port;
  482.  
  483.     msg->RBuf = NULL;
  484.     msg->RLen = 0;
  485.     msg->RFlags = 0;
  486.     msg->Error    = 0;
  487.     msg->Confirm = NULL;
  488.  
  489.     LockAddr(IPCLock);
  490.     if (name) {
  491.     port = (IPCPORT *)FindName(&IPCList, name);
  492.     } else {
  493.     port = GetHead(&IPCList);
  494.     }
  495.     msg->ToPort = port;
  496.     if (port) {
  497.     if ((port->Flags & IF_ALLOC) && !(msg->TFlags & IF_ALLOC)) {
  498.         if ((msg->TBuf = Duplicate(msg->TBuf, msg->TLen)) == NULL) {
  499.         msg->Error = PERR_NOMEM;
  500.         lReplyIPC(msg, NULL, 0, IF_ERROR);
  501.         return(msg);
  502.         }
  503.         msg->TFlags |= IF_ALLOC;
  504.     }
  505.     PutMsg(port, msg);
  506.     UnLockAddr(IPCLock);
  507.     } else {
  508.     UnLockAddr(IPCLock);
  509.     lReplyIPC(msg, NULL, 0, IF_ERROR|IF_NOTFND|IF_NOAPP);
  510.     }
  511.     return(msg);
  512. }
  513.  
  514. /*
  515.  *  DoIPC2(name, msg, collfunc, collport)
  516.  *
  517.  *  Synchronous IPC routine.  To prevent lockouts in case the calling task
  518.  *  also owns an IPC port, if this port is provided 'collfunc' will
  519.  *  automatically be called if new requests arrive while we are waiting
  520.  *  for our request to complete.  This call is reentrant.
  521.  */
  522.  
  523. void
  524. lDoIPC2(name, msg, func, port)
  525. char *name;
  526. IPCMSG *msg;
  527. void (*func)();
  528. PORT *port;
  529. {
  530.     SendIPC2(name, msg);        /*  send the message            */
  531.     if (port) {
  532.     register long mask1 = 1 << port->mp_SigBit;
  533.     register long mask2 = 1 << msg->Msg.mn_ReplyPort->mp_SigBit;
  534.  
  535.     while (!CheckMsg(msg)) {
  536.         if (CheckPort(port)) {
  537.         CCall(func, port);
  538.         continue;
  539.         }
  540.         Wait(mask1 | mask2);
  541.     }
  542.     }
  543.     WaitMsg(msg);
  544. }
  545.  
  546. /*
  547.  *  (void )ReplyIPC(msg, buf, len, flags)
  548.  */
  549.  
  550. lReplyIPC(msg, buf, len, flags)
  551. register IPCMSG *msg;
  552. APTR buf;
  553. long len, flags;
  554. {
  555.     if (buf && !(flags & (IF_NOCOPY|IF_ALLOC|IF_NOTFND))) {
  556.     buf = Duplicate(buf, len);
  557.     flags |= IF_ALLOC;
  558.     }
  559.     if (buf || !(flags & IF_NOTFND)) {
  560.     if ((msg->RFlags & IF_ALLOC) && msg->RBuf && buf != msg->RBuf)
  561.         FreeMem(msg->RBuf, msg->RLen);
  562.     msg->RBuf = buf;
  563.     msg->RLen = len;
  564.     }
  565.     msg->RFlags = flags;
  566.     LockAddr(IPCLock);
  567.     if (msg->RFlags & IF_GLOBAL) {
  568.     register IPCPORT *next;
  569.  
  570.     do {
  571.         next = GetSucc(next);
  572.     } while (next && !(next->Flags & IF_GLOBAL));
  573.     if (next) {
  574.         msg->ToPort = next;
  575.         PutMsg(next, msg);
  576.     } else {
  577.         if ((msg->TFlags & IF_ALLOC) && msg->TBuf) {
  578.         FreeMem(msg->TBuf, msg->TLen);
  579.         msg->TBuf = NULL;
  580.         }
  581.         ReplyMsg(msg);
  582.     }
  583.     UnLockAddr(IPCLock);
  584.     return;
  585.     }
  586.     if (flags & IF_NOTFND) {
  587.     register IPCPORT *next = GetSucc(msg->ToPort);
  588.     if (next && strcmp(msg->ToPort->Port.mp_Node.ln_Name, next->Port.mp_Node.ln_Name) == 0) {
  589.         msg->ToPort = next;
  590.         PutMsg(next, msg);
  591.     } else {
  592.         if ((msg->TFlags & IF_ALLOC) && msg->TBuf) {
  593.         FreeMem(msg->TBuf, msg->TLen);
  594.         msg->TBuf = NULL;
  595.         }
  596.         ReplyMsg(msg);
  597.         msg->RFlags |= IF_ERROR;
  598.     }
  599.     UnLockAddr(IPCLock);
  600.     return;
  601.     }
  602.     UnLockAddr(IPCLock);
  603.     if ((msg->TFlags & IF_ALLOC) && msg->TBuf) {
  604.     FreeMem(msg->TBuf, msg->TLen);
  605.     msg->TBuf = NULL;
  606.     }
  607.     ReplyMsg(msg);
  608.     return;
  609. }
  610.  
  611. /*
  612.  * (void) lFreeIPC(msg)
  613.  *
  614.  *  Free space associated with the reply buffer and possibly the message
  615.  *  itself.  This call MUST be made after you receive a reply to your
  616.  *  message.
  617.  */
  618.  
  619. void
  620. lFreeIPC(msg)
  621. register IPCMSG *msg;
  622. {
  623.     if ((msg->RFlags & IF_ALLOC) && msg->RBuf) {
  624.     FreeMem(msg->RBuf, msg->RLen);
  625.     msg->RBuf = NULL;
  626.     }
  627.     if (msg->Confirm)                   /*  Confirmation requested  */
  628.     CCall(msg->Confirm, msg);
  629.     if (msg->TFlags & IF_ALLOCMSG)      /*  Message was allocated   */
  630.     FreeMem(msg, msg->Msg.mn_Length);
  631. }
  632.  
  633. APTR
  634. Duplicate(buf, len)
  635. APTR buf;
  636. long len;
  637. {
  638.     APTR newbuf;
  639.     if (newbuf = AllocMem(len, TypeOfMem(buf))) {
  640.     BMov(buf, newbuf, len);
  641.     return(newbuf);
  642.     }
  643.     return(NULL);
  644. }
  645.  
  646. #asm
  647.  
  648.         ;    CCall(funcptr, argument)
  649.  
  650. _CCall:     movem.l 4(sp),A0/A1
  651.         movem.l D2/D3/A4/A5/A6,-(sp)
  652.         move.l  A1,-(sp)
  653.         jsr     (A0)
  654.         addq.l  #4,sp
  655.         movem.l (sp)+,D2/D3/A4/A5/A6
  656.         rts
  657. #endasm
  658.  
  659. \Rogue\Monster\
  660. else
  661.   echo "will not over write src/ipc.c"
  662. fi
  663. if [ `wc -c src/ipc.c | awk '{printf $1}'` -ne 12876 ]
  664. then
  665. echo `wc -c src/ipc.c | awk '{print "Got " $1 ", Expected " 12876}'`
  666. fi
  667. if `test ! -s src/misc.c`
  668. then
  669. echo "writing src/misc.c"
  670. cat > src/misc.c << '\Rogue\Monster\'
  671.  
  672. /*
  673.  *  MISC.C
  674.  *
  675.  *  General Stuff... mostly in assembly.
  676.  */
  677.  
  678. #include <local/typedefs.h>
  679.  
  680. typedef struct {
  681.     NODE     ml_Node;
  682.     uword    ml_NumEntries;
  683.     MEMENTRY ml_ME[2];
  684. } MYMEMLIST;
  685.  
  686. APTR
  687. lGetTaskData(name, bytes)
  688. char *name;
  689. long bytes;
  690. {
  691.     extern EXECBASE *SysBase;
  692.     extern void *FindName2();
  693.     register LIST *list;
  694.     register MEMLIST *ml;
  695.  
  696.     list = &SysBase->ThisTask->tc_MemEntry;
  697.     if (ml = FindName2(list, name))
  698.     return(ml->ml_ME[0].me_Un.meu_Addr);
  699.     if (!list->lh_Head)
  700.     NewList(list);
  701.     {
  702.     MYMEMLIST Ml;
  703.  
  704.     Ml.ml_NumEntries = 2;
  705.     Ml.ml_ME[0].me_Un.meu_Reqs = MEMF_PUBLIC|MEMF_CLEAR;
  706.     Ml.ml_ME[0].me_Length = bytes;
  707.     Ml.ml_ME[1].me_Un.meu_Reqs = MEMF_PUBLIC;
  708.     Ml.ml_ME[1].me_Length = strlen(name)+1;
  709.     if (ml = AllocEntry(&Ml)) {
  710.         ml->ml_Node.ln_Name = (char *)ml->ml_ME[1].me_Un.meu_Addr;
  711.         strcpy(ml->ml_Node.ln_Name, name);
  712.         AddHead(list, ml);
  713.         return(ml->ml_ME[0].me_Un.meu_Addr);
  714.     }
  715.     }
  716.     return(NULL);
  717. }
  718.  
  719. lFreeTaskData(name)
  720. char *name;
  721. {
  722.     extern EXECBASE *SysBase;
  723.     extern void *FindName2();
  724.     register MEMLIST *ml;
  725.  
  726.     if (ml = FindName2(&SysBase->ThisTask->tc_MemEntry, name)) {
  727.     Remove(ml);
  728.     FreeEntry(ml);
  729.     return(1);
  730.     }
  731.     return(0);
  732. }
  733.  
  734.  
  735. #asm
  736.  
  737.  
  738.         include "exec/types.i"
  739.         include "exec/ports.i"
  740.         include "exec/tasks.i"
  741.         include "exec/execbase.i"
  742.         include "exec/ables.i"
  743.         include "exec/memory.i"
  744.  
  745.         ;   NOTE:   LockAddr/UnLockAddr referenced elsewhere in
  746.         ;        this library
  747.  
  748.         ;   MISC.ASM
  749.  
  750.         public    _lWildCmp    ; Wildcard compare
  751.         public    _lWaitMsg    ; Wait for a message to be replied
  752.         public    _lCheckMsg    ; Check if message has been returned
  753.         public    _lCheckPort    ; Check if message pending on port
  754.         public    _lDoSyncMsg    ; Put and Wait for a message
  755.         public    _lLockAddr
  756.         public    _lLockAddrB
  757.         public    _lUnLockAddr
  758.         public    _lUnLockAddrB
  759.         public    _lFindName2
  760.  
  761.         public    _LVOWait
  762.         public    _LVORemove
  763.         public    _LVODisable
  764.         public    _LVOEnable
  765.         public    _LVOFindTask
  766.         public    _LVOSignal
  767.         public    _LVOForbid
  768.         public    _LVOPermit
  769.         public    _LVOPutMsg
  770.  
  771.  
  772. _lDoSyncMsg:    movem.l A2/A3/A6,-(sp)              ; A0=port, A1=msg
  773.         move.l    4,A6                ; A6=execbase
  774.  
  775.         sub.w    #MP_SIZE,sp            ; initialize reply port
  776.         move.b    #NT_MSGPORT,LN_TYPE(sp)
  777.         move.b    #PA_SIGNAL,MP_FLAGS(sp)
  778.         move.b    #4,MP_SIGBIT(sp)            ; EXEC semaphore signal
  779.         move.l    ThisTask(A6),MP_SIGTASK(sp)
  780.         lea    MP_MSGLIST(sp),A2
  781.         lea    MP_MSGLIST+4(sp),A3
  782.         move.l    A3,(A2)                     ; &tail -> head
  783.         move.l    #0,(A3)                     ; NULL  -> tail
  784.         move.l    A2,8(A2)                    ; &head -> tailpred
  785.  
  786.         move.l    sp,MN_REPLYPORT(A1)
  787.         move.l    A1,A2                ; save message
  788.         jsr    _LVOPutMsg(A6)              ; send the message
  789.         move.l    A2,A0
  790.         bsr    _lWaitMsg            ; wait for reply
  791.  
  792.         add.w    #MP_SIZE,sp
  793.         movem.l (sp)+,A2/A3/A6
  794.         rts
  795.  
  796. _lCheckMsg:    moveq.l #0,D0
  797.         cmp.b    #NT_MESSAGE,LN_TYPE(A0) ;NT_MESSAGE == not replied
  798.         beq    .lcm1
  799.         move.l    A0,D0
  800. .lcm1        rts
  801.  
  802. _lCheckPort:    moveq.l #0,D0
  803.         move.l    MP_MSGLIST+LH_HEAD(A0),A0
  804.         tst.l    (A0)                    ;list empty?
  805.         beq    .lcp1
  806.         move.l    A0,D0            ;no, return first element
  807. .lcp1        rts
  808.  
  809. _lWaitMsg:                    ;A0 = message to wait for
  810.         movem.l A2/A3/A6,-(sp)
  811.         move.l    A0,A2            ;A2 = message
  812.         move.l    MN_REPLYPORT(A0),A3     ;A3 = replyport
  813.         move.l    4,A6            ;A6 = execbase
  814. .wmloop     cmp.b    #NT_MESSAGE,LN_TYPE(A2) ;while msg not replied
  815.         bne    .wm1
  816.         move.b    MP_SIGBIT(A3),D1        ;Wait on port signal
  817.         moveq.l #0,D0
  818.         bset.l    D1,D0
  819.         jsr    _LVOWait(A6)
  820.         bra    .wmloop
  821. .wm1        jsr    _LVODisable(A6)         ;remove from port
  822.         move.l    A2,A1            ;A1 = message (A2)
  823.         jsr    _LVORemove(A6)
  824.         jsr    _LVOEnable(A6)
  825.         move.l    A2,D0            ;return message
  826.         movem.l (sp)+,A2/A3/A6
  827.         rts
  828.  
  829.  
  830.         ;WILDCMP(wild:D0, name:D1)
  831.         ;
  832.         ;   Handles * and ?
  833.         ;
  834.         ;result:  D0, 0 = no match, 1 = match
  835.         ;
  836.         ;auto:
  837.         ;   D2    bi
  838.         ;   A2    wildcard string
  839.         ;   A3    name     string
  840.         ;   A4    back-array (of size MAXB * 2 * 4)
  841.  
  842.  
  843. MAXB        EQU    8
  844.  
  845. _lWildCmp:    movem.l D2/A2-A4,-(sp)
  846.         move.l    D0,A2
  847.         move.l    D1,A3
  848.         sub.l    #MAXB*2*8,sp
  849.         move.l    sp,A4
  850.  
  851.         moveq.l #0,D2
  852.  
  853. .wcloop     moveq.l #1,D0
  854.         move.b    (A2),D1
  855.         bne    .w1
  856.         tst.b    (A3)
  857.         beq    .wcdone
  858.  
  859. .w1        cmp.b    #'*',D1
  860.         bne    .w10
  861.         cmp.w    #MAXB,D2
  862.         bne    .w2
  863.         moveq.l #-1,D0        ; error
  864.         bra    .wcdone
  865. .w2        move.w    D2,D0        ; back[bi][0] = w  i.e. back+bi*8
  866.         asl.w    #3,D0        ; back[bi][1] = n
  867.         move.l    A2,(A4,D0.w)
  868.         move.l    A3,4(A4,D0.w)
  869.         addq.w    #1,D2
  870.         addq.l    #1,A2
  871.         bra    .wcloop
  872.  
  873. .wgoback    subq.w    #1,D2
  874.         bmi    .w5
  875.         move.w    D2,D0
  876.         asl.w    #3,D0
  877.         move.l    4(A4,D0.w),A0
  878.         tst.b    (A0)
  879.         beq    .wgoback
  880. .w5        tst.w    D2
  881.         bmi    .wcret0
  882.         move.w    D2,D0
  883.         asl.w    #3,D0
  884.         move.l    (A4,D0.w),A2
  885.         addq.l    #1,A2
  886.         add.l    #1,4(A4,D0.w)
  887.         move.l    4(A4,D0.w),A3
  888.         addq.l    #1,D2
  889.         bra    .wcloop
  890.  
  891. .w10        cmp.b    #'?',D1
  892.         bne    .w20
  893.         tst.b    (A3)
  894.         bne    .wcbreak
  895.         tst.w    D2
  896.         bne    .wgoback
  897.         bra    .wcret0
  898.  
  899. .w20        move.b    (A3),D0
  900.         cmp.b    #'A',D0
  901.         blo    .w21
  902.         cmp.b    #'Z',D0
  903.         bhi    .w21
  904.         or.b    #$20,D0
  905. .w21        move.b    (A2),D1
  906.         cmp.b    #'A',D1
  907.         blo    .w22
  908.         cmp.b    #'Z',D1
  909.         bhi    .w22
  910.         or.b    #$20,D1
  911. .w22        cmp.b    D0,D1
  912.         beq    .wcbreak
  913.         tst.w    D2
  914.         bne    .wgoback
  915.         bra    .wcret0
  916.  
  917. .wcbreak    tst.b    (A2)+
  918.         bne    .wcb1
  919.         subq.l    #1,A2
  920. .wcb1        tst.b    (A3)+
  921.         bne    .wcb2
  922.         subq.l    #1,A3
  923. .wcb2        bra    .wcloop
  924.  
  925. .wcret0     moveq.l #0,D0
  926. .wcdone     add.l    #MAXB*2*8,sp
  927.         movem.l (sp)+,D2/A2-A4
  928.         rts
  929.  
  930.         ;   long var[2] = { 0, 0 };
  931.         ;
  932.         ;   These routines provide fast exclusive
  933.         ;   locks.  Up to 8 independant locks may be used for
  934.         ;   each 4 byte address.
  935.         ;
  936.         ;   LockAddr(&var[0]:A0)
  937.         ;   LockAddrB(bit:D0, &var[0]:A0)
  938.         ;   UnLockAddr(&var[0]:A0)
  939.         ;   UnLockAddrB(bit:D0, &var[0]:A0)
  940.  
  941.  
  942. _lLockAddr:    moveq.l #0,D0            ; bit 0
  943. _lLockAddrB:    bset.b    D0,4(A0)                ; attempt to gain lock
  944.         bne    .la10
  945.         rts                ; was clear, so got it
  946. .la10        movem.l A2/A6,-(sp)             ; else failed,
  947.         move.l    4,A6            ; A6 = SYSBase
  948.         FORBID
  949.         bset.b    D0,4(A0)                ; try again
  950.         beq    .la20            ; got it!
  951.  
  952.         move.w    D0,-(sp)                ; bit#    12(sp)
  953.         move.l    ThisTask(A6),-(sp)      ; task#    8(sp)
  954.         move.l    A0,-(sp)                ; &var     4(sp)
  955.         move.l    (A0),-(sp)              ; Next      (sp)
  956.         move.l    sp,(A0)                 ; (put at head of list)
  957. .la15        moveq.l #$10,D0         ; wait (semaphore signal)
  958.         jsr    _LVOWait(A6)
  959.  
  960.         move.w    12(sp),D0               ; try for lock
  961.         move.l    4(sp),A0
  962.         bset.b    D0,4(A0)
  963.         bne    .la15            ; loop until get it
  964.  
  965. .la16        cmp.l    (A0),sp                 ; unlink, find our node!
  966.         beq    .la18
  967.         move.l    (A0),A0
  968.         bra    .la16
  969. .la18        move.l    (sp),(A0)
  970.         add.w    #14,sp
  971. .la20
  972.         PERMIT
  973.         movem.l (sp)+,A2/A6
  974.         rts
  975.  
  976. _lUnLockAddr:    moveq.l #0,D0            ; bit 0
  977. _lUnLockAddrB:    bclr.b    D0,4(A0)                ; clear lock bit
  978.         move.l    (A0),D1                 ; anybody waiting?
  979.         beq    .ulrts            ; no, rts
  980.  
  981.         movem.l D2/A2/A6,-(sp)          ; yes, wake 'm all up
  982.         move.b    D0,D2            ; D2 = bit#
  983.         move.l    4,A6            ; A6 = SYSBase
  984.         FORBID
  985.  
  986.         move.l    (A0),D1                 ; get pointer again after FORBID
  987.         beq    .ul20            ; no, rts (close a window)
  988.  
  989. .ul10        move.l    D1,A2            ; A2 = node
  990.         cmp.b    13(A2),D2               ; waiting on our bit #?
  991.         bne    .ul18            ; no
  992.         move.l    8(A2),A1                ; yes, signal the node
  993.         moveq.l #$10,D0
  994.         jsr    _LVOSignal(A6)          ; signal EVERYONE waiting
  995. .ul18        move.l    (A2),D1                 ; next
  996.         bne    .ul10
  997.  
  998. .ul20
  999.         PERMIT
  1000.         movem.l (sp)+,D2/A2/A6
  1001. .ulrts        rts
  1002.  
  1003.         ;   FindName2(list:D0, name:A0)
  1004.         ;
  1005.         ;   Search the node list as in FindName(), but also ignore
  1006.         ;   NULL ln_name entries, which FindName() does not do.  This
  1007.         ;   routine will also return NULL if given an uninitialized
  1008.         ;   list header (completely zero'd).  Finally, it will not
  1009.         ;   bother to do a string compare if the two pointers are
  1010.         ;   the same.
  1011.  
  1012. _lFindName2:    movem.l A2/A3,-(sp)
  1013.         move.l    D0,A1
  1014.         tst.l    (A1)                        ; uninitialized list header
  1015.         beq    .fn2fail
  1016. .fn2loop    move.l    (A1),A1                     ; get first/next node
  1017.         tst.l    (A1)                        ; end of list?
  1018.         beq    .fn2fail
  1019.         move.l    LN_NAME(A1),D0              ; name
  1020.         beq    .fn2loop            ; NULL, skip
  1021.         cmp.l    D0,A0                ; pointers are the same!
  1022.         beq    .fn2succ            ;  don't bother w/cmp.
  1023.         move.l    D0,A2
  1024.         move.l    A0,A3
  1025. .fn2l2        cmpm.b    (A2)+,(A3)+
  1026.         bne    .fn2loop
  1027.         tst.b    -1(A2)
  1028.         bne    .fn2l2
  1029. .fn2succ    move.l    A1,D0
  1030.         movem.l (sp)+,A2/A3
  1031.         rts
  1032. .fn2fail    moveq.l #0,D0
  1033.         movem.l (sp)+,A2/A3
  1034.         rts
  1035.  
  1036. #endasm
  1037.  
  1038. \Rogue\Monster\
  1039. else
  1040.   echo "will not over write src/misc.c"
  1041. fi
  1042. if [ `wc -c src/misc.c | awk '{printf $1}'` -ne 8171 ]
  1043. then
  1044. echo `wc -c src/misc.c | awk '{print "Got " $1 ", Expected " 8171}'`
  1045. fi
  1046. if `test ! -s src/newres.c`
  1047. then
  1048. echo "writing src/newres.c"
  1049. cat > src/newres.c << '\Rogue\Monster\'
  1050.  
  1051.  
  1052. /*
  1053.  *FUNC= GetRes        A0
  1054.  *FUNC= FreeRes     A0
  1055.  *FUNC= FreeAllRes    A0
  1056.  *FUNC= ChownRes    D0/D1/A0
  1057.  *FUNC= UnLinkAllRes    A0
  1058.  *FUNC= ReLinkAllRes    A0
  1059.  *FUNC= SetResFlags    D0/D1/A0
  1060.  *FUNC= AddRes        D0/D1/D2/A0
  1061.  *FUNC= RemRes        A0
  1062.  *FUNC= GetResInfo    D0/D1/A0
  1063.  *FUNC= GetResList    D0/D1/D2/A0
  1064.  *FUNC= GetFileList    D0/D1/D2/A0
  1065.  *FUNC= AddPrivResFile    D0/D1
  1066.  *FUNC= RemPrivResFiles A0
  1067.  *FUNC= AddGlobResFile    D0/D1
  1068.  *FUNC= RemGlobResFiles A0
  1069.  *FUNC= AddResSwapDir    D0/D1/A0
  1070.  *FUNC= RemResSwapDirs    A0
  1071.  *FUNC= NULL        -
  1072.  *FUNC= NULL        -
  1073.  *FUNC= NULL        -
  1074.  *FUNC= NULL        -
  1075.  *FUNC= NULL        -
  1076.  *FUNC= NULL        -
  1077.  *FUNC= NULL        -
  1078.  *FUNC= NULL        -
  1079.  *FUNC= NULL        -
  1080.  *FUNC= NULL        -
  1081.  *FUNC= NULL        -
  1082.  *FUNC= NULL        -
  1083.  *FUNC= NULL        -
  1084.  *FUNC= NULL        -
  1085.  *
  1086.  */
  1087.  
  1088. #include <local/typedefs.h>
  1089. #include <local/res.h>
  1090. #include "file.h"
  1091.  
  1092. /*
  1093.  *  resptr = GetRes(resnametype)        char *resnametype;
  1094.  *
  1095.  *  (1) The resource is SHARED, is tagged with its name, then
  1096.  *    (a) if swapped, swap in
  1097.  *    (b) incr. ref. count.
  1098.  *  (2) The resource is not shared, re-load from disk
  1099.  *
  1100.  */
  1101.  
  1102. GetRes(rnt)
  1103. register char *rnt;
  1104. {
  1105.     RMSG    RMsg;
  1106.     register char *str;
  1107.  
  1108.     for (str = rnt + strlen(rnt); str >= rnt && *str != '.'; --str);
  1109.     RMsg.Arg1 = (long)rnt;
  1110.     RMsg.Arg2 = (long)str + 1;
  1111.     if ((RMsg.Arg3 = str - rnt) < 0)
  1112.     RMsg.Arg3 = 0;
  1113.     RMsg.Arg4 = strlen(str + 1);
  1114.     DoSyncMsg(&ResPort, &RMsg);
  1115.     return(RMsg.Res1);
  1116. }
  1117.  
  1118.     resptr= GetRes(resnametype)             char *resnametype;
  1119.  
  1120.     This function retrieves the requested resource, doing any
  1121.     translations required to get the resource into the requested
  1122.     type.  NULL is returned if the resource could not be found
  1123.     or could not be translated to the requested type.
  1124.  
  1125.     In-Memory private resources are searched first, then the private
  1126.     resource files for the task, then In-Memory system resources, then
  1127.     the global resource files for the system.  Openning an already-open
  1128.     resource causes one of two actions depending on whether the resource
  1129.     is shared or not.  If shared, the reference count is simply
  1130.     incremented, otherwise a private copy of the resource is made.
  1131.  
  1132.     Example:    Win = GetRes("Charlie.Window");
  1133.  
  1134.     error = FreeRes(resptr)
  1135.  
  1136.     Free a resource that you retrieved via GetRes().  Only the task
  1137.     that owns the resource may free it (though several tasks may own
  1138.     a resource through duplication and ownership changes).    1 is
  1139.     returned on success, 0 on error.
  1140.  
  1141.     numres= FreeAllRes(task)
  1142.  
  1143.     Free all resources associated with the specified task (NULL for
  1144.     self).
  1145.  
  1146.     error = ChownRes(resptr, fromtask, totask)
  1147.  
  1148.     Change ownership of a resource from the source task to the
  1149.     destination task.  The resource must be owned by the source
  1150.     task or an error will occur (0 return value).  1 is returned
  1151.     on success.  NULL may be specified for either or both tasks
  1152.     meaning the calling task.
  1153.  
  1154.     handle= UnLinkAllRes(task)
  1155.  
  1156.     Unlink all resources associated with the specified task (NULL
  1157.     for self) and return a handle representing those resources.
  1158.  
  1159.     This is useful for shells and such to keep their resources from
  1160.     getting removed by commands they run.  Combined with the NUNLINK
  1161.     flag one can pass resources to a Command and keep the rest out of
  1162.     reach.
  1163.  
  1164.     (void)  ReLinkAllRes(handle, task)
  1165.  
  1166.     Link all the resources represented by the handle to the specified
  1167.     task (NULL for self).
  1168.  
  1169.     oldfl = SetResFlags(resptr, newflags, flagsmask)
  1170.  
  1171.     Modify the flags associated with a resource.  NOTE:  If multiple
  1172.     references to a shared resource exist, all are modified.  Some
  1173.     modifications may be disallowed by the system.    This call is
  1174.     normally used to modify the LOCKED and SWAPABLE flags (note that
  1175.     the SWAPABLE flag can be changed back and forth only for resource
  1176.     which support it).
  1177.  
  1178.     error = AddRes(resnametype, flags, ptr, ctlcode);
  1179.                             char *resnametype;
  1180.                             long flags;
  1181.                             APTR ptr;
  1182.                             long (*ctlcode)();
  1183.  
  1184.     Add a resource to the system.  The resource is placed either in
  1185.     the task's privately accessable in-memory resource list or
  1186.     in the system global accessable in-memory resource list depending
  1187.     on the specified flags.  One may now GetRes() the resource.
  1188.  
  1189.     ONLY VIRTUAL RESOURCES MAY BE ADDED IN THIS WAY.  The VIRTUAL
  1190.     and LOCKED flags are automatically set.
  1191.  
  1192.     If flags specifies a VIRTUAL resource
  1193.  
  1194.     error = RemRes(resname)
  1195.  
  1196.     Remove the specified resource.    An error will occur and the resource
  1197.     will not be removed (1) if it does not exist in memory, or (2) it
  1198.     is currently being referenced.    (Note: the resource is removed even
  1199.     if it is swapped or locked).
  1200.  
  1201.     error = GetResInfo(resname, &flags, &bytes)
  1202.  
  1203.     Get information on a resource.    Information may not exist for a
  1204.     resource if it is not currently in memory and would have to be
  1205.     translated to get to the right type.
  1206.  
  1207.     error = GetResList(wildcard, from, &av, &ac);
  1208.  
  1209.     from:    mask, bit 0  search private list
  1210.               1  search system list
  1211.               2  <not used>
  1212.               3  search in-memory private list
  1213.               4  search in-memory global list
  1214.  
  1215.     Return an ARGC/ARGV list of resource names.  Note that some names
  1216.     might be duplicated if searching multiple lists.  Restricting the
  1217.     search to in-memory lists give resources which are already in
  1218.     memory (but might be swapped out or removed at any time for those
  1219.     with no references)
  1220.  
  1221.                  RESOURCE FILES
  1222.  
  1223.     error = GetFileList(wildcard, from, &av, &ac);
  1224.  
  1225.     from:    mask, bit 0  search private list
  1226.               1  search system list
  1227.               2  search swap list
  1228.  
  1229.     Return an ARGC/ARGV list of the files which match the specified
  1230.     wildcard from the private list, system list, or system swap dir
  1231.     list (in which case you get directory names).  This list has been
  1232.     allocated, and can be freed as follows:
  1233.  
  1234.         Loop through all entries for (i = 0; i < ac; ++i)
  1235.                     FreeMem(av[i], strlen(av[i])+1);
  1236.         Free the array itself:  FreeMem(av, sizeof(char *) * (ac+1));
  1237.  
  1238.     num   = AddPrivResFile(filename, pri)
  1239.  
  1240.     Add a file name to the list of resource files for this task.  These
  1241.     are scanned before global files when a resource is requested.  All
  1242.     files in the list are write protected (i.e. a shared lock is kept
  1243.     for each file).  Thus, such files cannot be updated until removed
  1244.     from the list.
  1245.  
  1246.     Can also be used to modify the priority of an existing file
  1247.  
  1248.     num   = RemPrivResFiles(wildcard)
  1249.  
  1250.     Remove zero or more file names from the list of resource files for
  1251.     this task.  A wildcard pattern (* and ?) is accepted.
  1252.  
  1253.     Note for command processors:    commands you run might execute
  1254.     this command for *.
  1255.  
  1256.     num   = AddGlobResFile(filename, pri)
  1257.  
  1258.     Same as AddPrivResFile() but applies to the system list, which is
  1259.     searched last and by any requesting task.  Wildcard file names are
  1260.     NOT accepted.  The file need not exist at this time, and references
  1261.     to unmounted volumes are allowed.
  1262.  
  1263.     Can also be used to modify the priority of an existing entry
  1264.  
  1265.     num   = RemGlobResFiles(wildcard)
  1266.  
  1267.     Remove zero or more resource files from the global list.  Again,
  1268.     a wildcard filename is accepted.
  1269.  
  1270.     num   = AddResSwapDir(dirname, pri, maxkbytes)      char *dirname;
  1271.                             char pri;
  1272.                             long maxkbytes
  1273.  
  1274.     Add a directory to the list of directories the resource system
  1275.     can swap to.  The maximum number of KBytes of material allowed
  1276.     in the directory should be specified.  You can also use this
  1277.     call to modify the priority and maxkbytes for an entry.
  1278.  
  1279.     The highest priority directories are used before lower priority
  1280.     directories.  Not all directories need be mounted, but if a swapin
  1281.     occurs from an unmounted directory a requester will appear.
  1282.  
  1283.     A lock is kept on each specified directory.
  1284.  
  1285.     num   = RemResSwapDirs(wildcard)
  1286.  
  1287.     Remove directories associated with the resource swap areas.
  1288.  
  1289.  
  1290. \Rogue\Monster\
  1291. else
  1292.   echo "will not over write src/newres.c"
  1293. fi
  1294. if [ `wc -c src/newres.c | awk '{printf $1}'` -ne 7611 ]
  1295. then
  1296. echo `wc -c src/newres.c | awk '{print "Got " $1 ", Expected " 7611}'`
  1297. fi
  1298. if `test ! -s src/mem.asm`
  1299. then
  1300. echo "writing src/mem.asm"
  1301. cat > src/mem.asm << '\Rogue\Monster\'
  1302.  
  1303.         ;   MEM.ASM
  1304.  
  1305.         public    _lBZero     ; Zero a block of memory
  1306.         public    _lBSet        ; Set a block of memory to (byte val)
  1307.         public    _lBMov        ; move a block of memory
  1308.         public    _lBCmp        ; compare two blocks of memory
  1309.  
  1310.         ;   BSET(buffer:D0, len:D1, byte:A0.B)
  1311.         ;   BZERO(buffer:D0, len:D1)
  1312.  
  1313. _lBZero:    move.w    #0,A0
  1314. _lBSet:     exg    A0,D0        ; A0 = buffer   (D0=byte)
  1315.         exg    D0,D1        ; D0 = length   (D1=byte)
  1316.         add.l    D0,A0        ; start at end of address
  1317.         cmp.l    #40,D0        ; unscientifically chosen
  1318.         bls    .bs2
  1319.         bra    .bs10
  1320. .bs1        move.b    D1,-(A0)    ; any count < 65536
  1321. .bs2        dbf    D0,.bs1
  1322.         rts
  1323.  
  1324.                     ; at least 2 bytes in count (D0)
  1325. .bs10        movem.l D2-D7/A2-A6,-(sp)   ;ant count > 4
  1326.         move.l    A0,D2
  1327.         btst.l    #0,D2        ; is it aligned?
  1328.         beq    .bs22
  1329.         move.b    D1,-(A0)    ; no, copy one byte
  1330.         subq.l    #1,D0
  1331.  
  1332. .bs22        andi.l    #$FF,D1     ; expand data D1.B -> D2-D7/A1-A6
  1333.         move.l    D1,D2        ; D1 000000xx   D2 000000xx
  1334.         asl.w    #8,D2        ;               0000xx00
  1335.         or.w    D2,D1        ;     0000xxxx
  1336.         move.w    D1,D2        ;     0000xxxx      0000xxxx
  1337.         swap    D2        ;     0000xxxx      xxxx0000
  1338.         or.l    D1,D2        ; D2.L
  1339.         move.l    D2,D3
  1340.         move.l    D2,D4
  1341.         move.l    D2,D5
  1342.         move.l    D2,D6
  1343.         move.l    D2,D7
  1344.         move.l    D2,A1
  1345.         move.l    D2,A2
  1346.         move.l    D2,A3
  1347.         move.l    D2,A4
  1348.         move.l    D2,A5
  1349.         move.l    D2,A6        ; D2-D7/A1-A6   (12 registers)
  1350.         move.l    #12*4,D1    ; bytes per transfer (48)
  1351. .bs30        sub.l    D1,D0        ; pre subtract
  1352.         bmi    .bs40
  1353. .bs31        movem.l D2-D7/A1-A6,-(A0)
  1354.         sub.l    D1,D0
  1355.         bpl    .bs31
  1356. .bs40        add.w    D1,D0        ; less than 48 bytes remaining
  1357.  
  1358.         move.w    #4,D1        ; by 4's
  1359.         sub.w    D1,D0
  1360.         bmi    .bs50
  1361. .bs41        move.l    D2,-(A0)
  1362.         sub.w    D1,D0
  1363.         bpl    .bs41
  1364. .bs50        add.w    D1,D0
  1365.         bra    .bs52
  1366. .bs51        move.b    D2,-(A0)    ; by 1's
  1367. .bs52        dbf    D0,.bs51
  1368.         movem.l (sp)+,D2-D7/A2-A6
  1369.         rts
  1370.  
  1371.         ;   BCMP(src:D0, dst:D1, len:A0)
  1372.  
  1373. _lBCmp:     exg    A0,D0        ;A0 = src, D0 = len
  1374.         exg    A1,D1        ;A1 = dst
  1375.  
  1376.         tst.l    D0
  1377.         beq    .bcsucc
  1378.         cmp.w    D0,D0        ;force Z bit
  1379.         bra    .bc2
  1380. .bc1        cmpm.b    (A0)+,(A1)+
  1381. .bc2        dbne    D0,.bc1
  1382.         bne    .bcfail
  1383.         sub.l    #$10000,D0
  1384.         bcc    .bc1
  1385. .bcsucc     moveq.l #1,D0        ;success!
  1386.         rts
  1387. .bcfail     moveq.l #0,D0        ;failure!
  1388.         rts
  1389.  
  1390.         ;   BMOV(src:D0, dst:D1, len:A0)
  1391.         ;
  1392.         ;   The memory move algorithm is somewhat more of a mess
  1393.         ;   since we must do it either ascending or decending.
  1394.  
  1395. _lBMov:     exg    A0,D0        ;A0 = src, D0 = len
  1396.         exg    A1,D1        ;A1 = dst
  1397.         cmp.l    A0,A1
  1398.         beq    .bmend
  1399.         bls    .bmup
  1400. .bmdown     adda.l    D0,A0        ;descending copy
  1401.         adda.l    D0,A1
  1402.         move.w    A0,D1        ;CHECK WORD ALIGNED
  1403.         btst.l    #0,D1
  1404.         bne    .bmdown1
  1405.         move.w    A1,D1
  1406.         btst.l    #0,D1
  1407.         bne    .bmdown1
  1408.         cmp.l    #259,D0         ;chosen by calculation.
  1409.         blo    .bmdown8
  1410.  
  1411.         move.l    D0,D1            ;overhead for bmd44: ~360
  1412.         divu    #44,D1
  1413.         bvs    .bmdown8        ;too big (> 2,883,540)
  1414.         movem.l D2-D7/A2-A6,-(sp)   ;use D2-D7/A2-A6 (11 regs)
  1415.         move.l    #11*4,D0
  1416.         bra    .bmd44b
  1417. .bmd44a     sub.l    D0,A0            ;8        total 214/44bytes
  1418.         movem.l (A0),D2-D7/A2-A6    ;12 + 8*11  4.86 cycles/byte
  1419.         movem.l D2-D7/A2-A6,-(A1)   ; 8 + 8*11
  1420. .bmd44b     dbf    D1,.bmd44a        ;10
  1421.         swap    D1            ;D0<15:7> already contain 0
  1422.         move.w    D1,D0            ;D0 = remainder
  1423.         movem.l (sp)+,D2-D7/A2-A6
  1424.  
  1425. .bmdown8    move.w    D0,D1            ;D1<2:0> = #bytes left later
  1426.         lsr.l    #3,D0            ;divide by 8
  1427.         bra    .bmd8b
  1428. .bmd8a        move.l    -(A0),-(A1)         ;20         total 50/8bytes
  1429.         move.l    -(A0),-(A1)         ;20         = 6.25 cycles/byte
  1430. .bmd8b        dbf    D0,.bmd8a        ;10
  1431.         sub.l    #$10000,D0
  1432.         bcc    .bmd8a
  1433.         move.w    D1,D0            ;D0 = 0 to 7 bytes
  1434.         and.l    #7,D0
  1435.         bne    .bmdown1
  1436.         rts
  1437.  
  1438. .bmd1a        move.b    -(A0),-(A1)         ;12         total 22/byte
  1439. .bmdown1                    ;        = 22 cycles/byte
  1440. .bmd1b        dbf    D0,.bmd1a        ;10
  1441.         sub.l    #$10000,D0
  1442.         bcc    .bmd1a
  1443.         rts
  1444.  
  1445. .bmup        move.w    A0,D1            ;CHECK WORD ALIGNED
  1446.         btst.l    #0,D1
  1447.         bne    .bmup1
  1448.         move.w    A1,D1
  1449.         btst.l    #0,D1
  1450.         bne    .bmup1
  1451.         cmp.l    #259,D0         ;chosen by calculation
  1452.         blo    .bmup8
  1453.  
  1454.         move.l    D0,D1            ;overhead for bmu44: ~360
  1455.         divu    #44,D1
  1456.         bvs    .bmup8            ;too big (> 2,883,540)
  1457.         movem.l D2-D7/A2-A6,-(sp)   ;use D2-D7/A2-A6 (11 regs)
  1458.         move.l    #11*4,D0
  1459.         bra    .bmu44b
  1460. .bmu44a     movem.l (A0)+,D2-D7/A2-A6   ;12 + 8*11  ttl 214/44bytes
  1461.         movem.l D2-D7/A2-A6,(A1)    ;8  + 8*11  4.86 cycles/byte
  1462.         add.l    D0,A1            ;8
  1463. .bmu44b     dbf    D1,.bmu44a        ;10
  1464.         swap    D1            ;D0<15:7> already contain 0
  1465.         move.w    D1,D0            ;D0 = remainder
  1466.         movem.l (sp)+,D2-D7/A2-A6
  1467.  
  1468. .bmup8        move.w    D0,D1            ;D1<2:0> = #bytes left later
  1469.         lsr.l    #3,D0            ;divide by 8
  1470.         bra    .bmu8b
  1471. .bmu8a        move.l    (A0)+,(A1)+         ;20         total 50/8bytes
  1472.         move.l    (A0)+,(A1)+         ;20         = 6.25 cycles/byte
  1473. .bmu8b        dbf    D0,.bmu8a        ;10
  1474.         sub.l    #$10000,D0
  1475.         bcc    .bmu8a
  1476.         move.w    D1,D0            ;D0 = 0 to 7 bytes
  1477.         and.l    #7,D0
  1478.         bne    .bmup1
  1479.         rts
  1480.  
  1481. .bmu1a        move.b    (A0)+,(A1)+
  1482. .bmup1
  1483. .bmu1b        dbf    D0,.bmu1a
  1484.         sub.l    #$10000,D0
  1485.         bcc    .bmu1a
  1486. .bmend        rts
  1487.  
  1488. \Rogue\Monster\
  1489. else
  1490.   echo "will not over write src/mem.asm"
  1491. fi
  1492. if [ `wc -c src/mem.asm | awk '{printf $1}'` -ne 4649 ]
  1493. then
  1494. echo `wc -c src/mem.asm | awk '{print "Got " $1 ", Expected " 4649}'`
  1495. fi
  1496. if `test ! -d util`
  1497. then
  1498.   mkdir util
  1499.   echo "mkdir util"
  1500. fi
  1501. if `test ! -s util/gtd.c`
  1502. then
  1503. echo "writing util/gtd.c"
  1504. cat > util/gtd.c << '\Rogue\Monster\'
  1505.  
  1506. /*
  1507.  *  GTD     -GetTaskData/FreeTaskData tester
  1508.  *
  1509.  *  Matthew Dillon, 30 Sep 1988
  1510.  *
  1511.  *  gtd             - show task memlist entries
  1512.  *  gtd <name>            - remove an entry
  1513.  *  gtd <name> <bytes>        - add/retrieve an entry, display it, then
  1514.  *                  store sequential values into the buffer.
  1515.  */
  1516.  
  1517. #include <stdio.h>
  1518. #include <local/typedefs.h>
  1519. #include <local/xmisc.h>
  1520.  
  1521. extern int Enable_Abort;
  1522. extern char *GetTaskData();
  1523.  
  1524. main(ac,av)
  1525. char *av[];
  1526. {
  1527.     char *ptr;
  1528.     long bytes;
  1529.     short i;
  1530.     TASK *task = FindTask(NULL);
  1531.  
  1532.     Enable_Abort = 0;
  1533.  
  1534.     if (openlibs(DRES_LIB) == 0)
  1535.     exit(1);
  1536.     if (ac == 1) {
  1537.     MEMLIST *ml;
  1538.     for (ml = GetHead(&task->tc_MemEntry); ml; ml = GetSucc(ml)) {
  1539.         printf("memlist %08lx %ld %s\n", ml, ml->ml_NumEntries,
  1540.         ((ml->ml_Node.ln_Name) ? ml->ml_Node.ln_Name : "NULL")
  1541.         );
  1542.     }
  1543.     goto fail;
  1544.     }
  1545.     bytes = atoi(av[2]);
  1546.     printf("%s,%ld :", av[1], bytes);
  1547.     fflush(stdout);
  1548.     if (ac == 2) {
  1549.     printf("result %ld\n", FreeTaskData(av[1]));
  1550.     } else {
  1551.     ptr = GetTaskData(av[1], bytes);
  1552.     if (!ptr) {
  1553.         puts("failed");
  1554.         goto fail;
  1555.     }
  1556.     printf("%08lx ", ptr);
  1557.     fflush(stdout);
  1558.     for (i = 0; i < bytes; ++i) {
  1559.         printf("%02x ", ptr[i]);
  1560.         ptr[i] = i;
  1561.     }
  1562.     }
  1563. fail:
  1564.     closelibs(-1);
  1565. }
  1566.  
  1567. \Rogue\Monster\
  1568. else
  1569.   echo "will not over write util/gtd.c"
  1570. fi
  1571. if [ `wc -c util/gtd.c | awk '{printf $1}'` -ne 1238 ]
  1572. then
  1573. echo `wc -c util/gtd.c | awk '{print "Got " $1 ", Expected " 1238}'`
  1574. fi
  1575. if `test ! -s util/testipc.c`
  1576. then
  1577. echo "writing util/testipc.c"
  1578. cat > util/testipc.c << '\Rogue\Monster\'
  1579.  
  1580. /*
  1581.  *  TESTIPC <appname> <file> <file> <file> ...    <inputfile
  1582.  *
  1583.  *  input file format:
  1584.  *
  1585.  *  appname delay file text
  1586.  *
  1587.  */
  1588.  
  1589. #include <local/typedefs.h>
  1590. #include <local/ipc.h>
  1591. #include <local/xmisc.h>
  1592. #include <stdio.h>
  1593.  
  1594. extern int Enable_Abort;
  1595.  
  1596. extern PORT *OpenIPC();
  1597.  
  1598. char **Av;
  1599. short Ac;
  1600.  
  1601. main(ac, av)
  1602. char *av[];
  1603. {
  1604.     PORT *port;
  1605.  
  1606.     Av = av;
  1607.     Ac = ac;
  1608.     if (ac == 1) {
  1609.     puts("TESTIPC <appname> <subname> ... <subname>  <inputfile");
  1610.     puts("input file format:");
  1611.     puts("<appname> <delay-1/50ths> <subname> <text>");
  1612.     exit(1);
  1613.     }
  1614.     Enable_Abort = 0;
  1615.     if (openlibs(DRES_LIB) <= 0) {
  1616.     puts("Unable to open dres.library");
  1617.     exit(1);
  1618.     }
  1619.     port = OpenIPC(av[1], 0);
  1620.     if (port == NULL) {
  1621.     puts("unable to open port");
  1622.     closelibs(-1);
  1623.     exit(1);
  1624.     }
  1625.     printf("port: %08lx\n", port);
  1626.     {
  1627.     char apname[32];
  1628.     long delay;
  1629.     char subname[32];
  1630.     char text[64];
  1631.     char tbuf[128];
  1632.     IPCMSG msg;
  1633.     extern void handler();
  1634.  
  1635.     BZero(&msg, sizeof(msg));
  1636.     msg.Msg.mn_ReplyPort = CreatePort(NULL, 0);
  1637.  
  1638.     puts("scanf");
  1639.     while (scanf("%s %ld %s %s", apname, &delay, subname, text) == 4) {
  1640.         printf("DO(%s %ld %s %s) ", apname, delay, subname, text);
  1641.         fflush(stdout);
  1642.         strcpy(tbuf, subname);
  1643.         strcpy(tbuf+strlen(subname)+1, text);
  1644.         msg.TBuf = (APTR)tbuf;
  1645.         msg.TLen = strlen(subname)+strlen(text)+2;
  1646.         DoIPC2(apname, &msg, handler, port);
  1647.         if (msg.RFlags & IF_NOTFND) {
  1648.         if (msg.RFlags & IF_NOAPP)
  1649.             puts("Application not found");
  1650.         else
  1651.             puts("subname not found");
  1652.         } else {
  1653.         if (msg.RFlags & IF_ERROR)
  1654.             printf("Error: %s\n", msg.RBuf);
  1655.         else
  1656.             printf("OK: %s\n", msg.RBuf);
  1657.         }
  1658.         FreeIPC(&msg);
  1659.         if (delay)
  1660.         Delay(delay);
  1661.         if (CheckPort(port))
  1662.         handler(port);
  1663.     }
  1664.     DeletePort(msg.Msg.mn_ReplyPort);
  1665.     }
  1666.     CloseIPC(port);
  1667.     closelibs(-1);
  1668. }
  1669.  
  1670. void
  1671. handler(port)
  1672. PORT *port;
  1673. {
  1674.     IPCMSG *msg;
  1675.     short i, j;
  1676.  
  1677.     while (msg = GetMsg(port)) {
  1678.     register char *ptr = (char *)msg->TBuf;
  1679.     printf("Received IPC command: %s  ", ptr);
  1680.     for (j = 0; ptr[j] && ptr[j] != ' '; ++j);
  1681.     for (i = 2; i < Ac; ++i) {
  1682.         if (strlen(Av[i]) == j && strncmp(Av[i], ptr, j) == 0)
  1683.         break;
  1684.     }
  1685.     if (i < Ac) {
  1686.         puts("MATCH");
  1687.         ReplyIPC(msg, "GotIt!", 7, 0);
  1688.     } else {
  1689.         puts("PASSED");
  1690.         ReplyIPC(msg, "Failed", 7, IF_NOTFND);
  1691.     }
  1692.     }
  1693. }
  1694.  
  1695. \Rogue\Monster\
  1696. else
  1697.   echo "will not over write util/testipc.c"
  1698. fi
  1699. if [ `wc -c util/testipc.c | awk '{printf $1}'` -ne 2309 ]
  1700. then
  1701. echo `wc -c util/testipc.c | awk '{print "Got " $1 ", Expected " 2309}'`
  1702. fi
  1703. if `test ! -s util/test.c`
  1704. then
  1705. echo "writing util/test.c"
  1706. cat > util/test.c << '\Rogue\Monster\'
  1707.  
  1708. /*
  1709.  *  TEST.C
  1710.  *
  1711.  *  Test Library Functions.
  1712.  */
  1713.  
  1714. #include <typedefs.h>
  1715. #include <stdio.h>
  1716.  
  1717. typedef struct Library LIB;
  1718.  
  1719. LIST ListA;
  1720. LIST ListB;
  1721. NODE Node1;
  1722. NODE Node2;
  1723. NODE Node3;
  1724. short Glob;
  1725.  
  1726. extern int Enable_Abort;
  1727.  
  1728. LIB *DMiscSupportBase;
  1729.  
  1730. extern LIB *OpenLibrary();
  1731. extern char *AllocMem();
  1732. extern char *GetHead();
  1733. extern char *GetTail();
  1734. extern char *GetSucc();
  1735. extern char *GetPred();
  1736. extern char *GetHeadOff();
  1737. extern char *GetTailOff();
  1738. extern char *GetSuccOff();
  1739. extern char *GetPredOff();
  1740. extern long srch();
  1741.  
  1742. main()
  1743. {
  1744.     Enable_Abort = 0;
  1745.     DMiscSupportBase = OpenLibrary("dmiscsup.library", 0);
  1746.     if (!DMiscSupportBase) {
  1747.     puts("Unable to open library");
  1748.     exit(1);
  1749.     }
  1750.     printf("library at: %08lx\n", DMiscSupportBase);
  1751.     printf("library flags: %02lx  Rev: %ld  OpenCnt: %ld\n",
  1752.     DMiscSupportBase->lib_Flags,
  1753.     DMiscSupportBase->lib_Revision,
  1754.     DMiscSupportBase->lib_OpenCnt
  1755.     );
  1756.     NewList(&ListA);
  1757.     NewList(&ListB);
  1758.     AddTail(&ListA, &Node1);
  1759.     AddTail(&ListA, &Node2);
  1760.     AddTail(&ListA, &Node3);
  1761.     printf("\nGetHead()         "); fflush(stdout);
  1762.     results((NODE *)GetHead(&ListA) == &Node1);
  1763.     results(GetHead(&ListB) == NULL);
  1764.     printf("\nGetTail()         "); fflush(stdout);
  1765.     results((NODE *)GetTail(&ListA) == &Node3);
  1766.     results(GetTail(&ListB) == NULL);
  1767.     printf("\nGetSucc()         "); fflush(stdout);
  1768.     results((NODE *)GetSucc(&Node1) == &Node2);
  1769.     results((NODE *)GetSucc(&Node3) == NULL);
  1770.     printf("\nGetPred()         "); fflush(stdout);
  1771.     results((NODE *)GetPred(&Node3) == &Node2);
  1772.     results((NODE *)GetPred(&Node1) == NULL);
  1773.     printf("\nGetHeadOff()      "); fflush(stdout);
  1774.     results(GetHeadOff(&ListA, 3) == (char *)&Node1 - 3);
  1775.     results(GetHeadOff(&ListB, 3) == NULL);
  1776.     printf("\nGetTailOff()      "); fflush(stdout);
  1777.     results(GetTailOff(&ListA, 3) == (char *)&Node3 - 3);
  1778.     results(GetTailOff(&ListB, 3) == NULL);
  1779.     printf("\nGetSuccOff()      "); fflush(stdout);
  1780.     results(GetSuccOff((char *)&Node1 - 3, 3) == (char *)&Node2 - 3);
  1781.     results(GetSuccOff((char *)&Node3 - 3, 3) == NULL);
  1782.     printf("\nGetPredOff()      "); fflush(stdout);
  1783.     results(GetPredOff((char *)&Node2 - 3, 3) == (char *)&Node1 - 3);
  1784.     results(GetPredOff((char *)&Node1 - 3, 3) == NULL);
  1785.     printf("\nSearchFwdNode()   "); fflush(stdout);
  1786.     Glob = 0; SearchFwdNodeOff(NULL, srch, 3, 27); results(Glob == 0);
  1787.     Glob = 0; SearchFwdNodeOff(GetHeadOff(&ListA, 3), srch, 3, 27); results(Glob == 3);
  1788.     printf("\nSearchRvsNode()   "); fflush(stdout);
  1789.     Glob = 0; SearchRvsNodeOff(NULL, srch, 3, 27); results(Glob == 0);
  1790.     Glob = 0; SearchRvsNodeOff(GetTailOff(&ListA, 3), srch, 3, 27); results(Glob == 3);
  1791.     puts("");
  1792.     wildtest();
  1793.     memory_test();
  1794.     RemLibrary(DMiscSupportBase);
  1795.     CloseLibrary(DMiscSupportBase);
  1796. }
  1797.  
  1798. results(bool)
  1799. {
  1800.     if (bool)
  1801.     printf("   ok");
  1802.     else
  1803.     printf(" fail");
  1804.     fflush(stdout);
  1805. }
  1806.  
  1807. srch(sptr, arg)
  1808. {
  1809.     ++Glob;
  1810.     printf(".");
  1811.     fflush(stdout);
  1812.     if (arg != 27)      /*  failure */
  1813.     return(1);
  1814.     return(NULL);
  1815. }
  1816.  
  1817. /*
  1818.  *  TEST:   WildCmp()
  1819.  */
  1820.  
  1821. wildtest()
  1822. {
  1823.     printf("WildCmp()         "); fflush(stdout);
  1824.     results(WildCmp("a??b", "axeb") == 1);
  1825.     results(WildCmp("a??b", "axebx")== 0);
  1826.     results(WildCmp("*/x*y*b", "a/x/u/xcharliey/b") == 1);
  1827.     results(WildCmp("*/x*y*b", "a/x/u/xcharlieq/b") == 0);
  1828.     puts("");
  1829. }
  1830.  
  1831. /*
  1832.  *  TEST:   BZero(), BSet(), BMov(), and BCmp();
  1833.  */
  1834.  
  1835. memory_test()
  1836. {
  1837.     long Size = 80000;        /*    MUST BE 80000    */
  1838.     short result;
  1839.     short i;
  1840.     char *ary1 = AllocMem(Size, MEMF_PUBLIC);
  1841.     char *ary2 = AllocMem(Size, MEMF_PUBLIC);
  1842.  
  1843.     printf("\nTEST MEMORY SUBROUTINES:\n");
  1844.     if (!ary1 || !ary2) {
  1845.     puts("    UNABLE TO ALLOCATE TWO CONTIGUOUS 80K SEGMENTS");
  1846.     puts("    THUS, CANNOT PERFORM MEMORY ROUTINES TEST.");
  1847.     goto fail;
  1848.     }
  1849.  
  1850.     /*
  1851.      *    Test BZero/BSet (both are the same subroutine, essentially).
  1852.      *    Test:    >64K, odd start, odd length.
  1853.      */
  1854.  
  1855.     printf(" BZero():   "); fflush(stdout);
  1856.  
  1857.     xbset(ary1, Size, 43);
  1858.     xbset(ary2, Size, 43);
  1859.     printf("."); fflush(stdout);
  1860.     BZero(ary1 + 1000, 20);
  1861.     BZero(ary1 + 1200, 70000);
  1862.     BZero(ary2 + 512 + 3, 70000);
  1863.     printf("."); fflush(stdout);
  1864.     results(xbcheck(ary1, 1000, 43));
  1865.     results(xbcheck(ary1 + 1000, 20, 0));
  1866.     results(xbcheck(ary1 + 1020, 1200 - 1020, 43));
  1867.     results(xbcheck(ary1 + 1200, 70000, 0));
  1868.     results(xbcheck(ary1 + 1200 + 70000, Size - 1200 - 70000, 43));
  1869.  
  1870.     printf("\n BSet():   "); fflush(stdout);
  1871.     xbset(ary1, Size, 43);
  1872.     xbset(ary2, Size, 43);
  1873.     printf("."); fflush(stdout);
  1874.     BSet(ary1 + 999, 21, 5);
  1875.     BSet(ary1 + 1201, 70001, 6);
  1876.     BSet(ary2 + 512 + 1, 69999, 7);
  1877.     printf("."); fflush(stdout);
  1878.     results(xbcheck(ary1, 999, 43));
  1879.     results(xbcheck(ary1 + 999, 21, 5));
  1880.     results(xbcheck(ary1 + 999 + 21, 1201 - 999 - 21, 43));
  1881.     results(xbcheck(ary1 + 1201, 70001, 6));
  1882.     results(xbcheck(ary1 + 1201 + 70001, Size - 1201 - 70001, 43));
  1883.     results(xbcheck(ary2, 512 + 1, 43));
  1884.     results(xbcheck(ary2 + 512 + 1, 69999, 7));
  1885.     results(xbcheck(ary2 + 512 + 1 + 69999, Size - 69999 - 512 - 1, 43));
  1886.  
  1887.     /*
  1888.      *    TEST BMov().  Odd start, overlapping blocks in forward and
  1889.      *    reverse.
  1890.      */
  1891.  
  1892.     printf("\n BMov(): 1"); fflush(stdout);
  1893.     xbset(ary1, Size, 43);
  1894.     xbset(ary2, Size, 43);
  1895.     xbiset(ary1 + 1001, 69999, 1);
  1896.     xbiset(ary2 + 1003, 70001, 1);
  1897.     BMov(ary1 + 1001, ary1 + 997, 69999);
  1898.     BMov(ary2 + 1003, ary2 + 1008, 70001);
  1899.     results(xbicheck(ary1 + 997, 69999, 1));
  1900.     results(xbicheck(ary2 + 1008, 70001, 1));
  1901.     results(xbcheck(ary1, 997, 43));
  1902.     results(xbcheck(ary1 + 1001 + 69999, Size - 1001 - 69999, 43));
  1903.     results(xbcheck(ary2, 1003, 43));
  1904.     results(xbcheck(ary2 + 1008 + 70001, Size - 1008 - 70001, 43));
  1905.     printf("\n BMov(): 2"); fflush(stdout);
  1906.     xbset(ary1, Size, 43);
  1907.     xbset(ary2, Size, 43);
  1908.     xbiset(ary1 + 1024, 70000, 1);
  1909.     xbiset(ary2 + 1024, 70000, 1);
  1910.     BMov(ary1 + 1024, ary1 + 1004, 70000);
  1911.     BMov(ary2 + 1024, ary2 + 1044, 70000);
  1912.     results(xbicheck(ary1 + 1004, 70000, 1));
  1913.     results(xbicheck(ary2 + 1044, 70000, 1));
  1914.     results(xbcheck(ary1, 1004, 43));
  1915.     results(xbcheck(ary1 + 1024 + 70000, Size - 70000 - 1024, 43));
  1916.     results(xbcheck(ary2, 1024, 43));
  1917.     results(xbcheck(ary1 + 1044 + 70000, Size - 70000 - 1044, 43));
  1918.     puts("");
  1919.     printf(" SPEEDTEST (K/sec BMov lw bndry, fastmem): %ld K/sec\n", speedtest(MEMF_FAST, 0, 0));
  1920.     printf(" SPEEDTEST (K/sec BSet lw bndry, fastmem): %ld K/sec\n", speedtest(MEMF_FAST, 1, 0));
  1921.     printf(" SPEEDTEST (K/sec BMov lw bndry, chipmem): %ld K/sec\n", speedtest(MEMF_CHIP, 0, 0));
  1922.     printf(" SPEEDTEST (K/sec BSet lw bndry, chipmem): %ld K/sec\n", speedtest(MEMF_CHIP, 1, 0));
  1923.     puts("");
  1924.     printf(" SPEEDTEST (K/sec BMov by bndry, fastmem): %ld K/sec\n", speedtest(MEMF_FAST, 0, 1));
  1925.     printf(" SPEEDTEST (K/sec BMov by bndry, chipmem): %ld K/sec\n", speedtest(MEMF_CHIP, 0, 1));
  1926. fail:
  1927.     if (ary1)
  1928.     FreeMem(ary1, Size);
  1929.     if (ary2)
  1930.     FreeMem(ary2, Size);
  1931. }
  1932.  
  1933. speedtest(memtype, zero, off)
  1934. {
  1935.     char *buf = AllocMem(65536+256, memtype);
  1936.     short i;
  1937.     long s;
  1938.  
  1939.     if (!buf)
  1940.     return(0);
  1941.     s = ltm();
  1942.     for (i = 0; i < 128; ++i) {
  1943.     if (zero)
  1944.         BSet(buf + off, 65536, 1);
  1945.     else
  1946.         BMov(buf + off, buf + 128 + off, 65536);
  1947.     }
  1948.     s = ltm() - s;          /*  1/50ths second for 64K * 128 */
  1949.     FreeMem(buf, 65536+256);
  1950.     return(64 * 128 * 50 / s);
  1951. }
  1952.  
  1953. ltm()
  1954. {
  1955.     long st[3];
  1956.  
  1957.     DateStamp(st);
  1958.     return(st[2] + 50 * 60 * st[1] + 50 * 60 * 60 * 24 * st[0]);
  1959. }
  1960.  
  1961. xbset(s, n, v)
  1962. register char *s;
  1963. register long n;
  1964. register char v;
  1965. {
  1966.     while (n--)
  1967.     *s++ = v;
  1968. }
  1969.  
  1970. xbiset(s, n, v)
  1971. register char *s;
  1972. register long n;
  1973. register char v;
  1974. {
  1975.     while (n--) {
  1976.     ++v;
  1977.     *s++ = v;
  1978.     }
  1979. }
  1980.  
  1981.  
  1982. xbcheck(s, n, v)
  1983. register char *s;
  1984. register long n;
  1985. register char v;
  1986. {
  1987.     char *orig = s;
  1988.     short errs = 255;
  1989.     while (n--) {
  1990.     if (*s++ != v) {
  1991.         if (errs) {
  1992.         --errs;
  1993.         printf("(%ld)", s - orig - 1);
  1994.         } else {
  1995.         printf("giveup");
  1996.         return(0);
  1997.         }
  1998.     }
  1999.     }
  2000.     return(errs == 255);
  2001. }
  2002.  
  2003. xbicheck(s, n, v)
  2004. register char *s;
  2005. register long n;
  2006. register char v;
  2007. {
  2008.     char *orig = s;
  2009.     short errs = 255;
  2010.     while (n--) {
  2011.     ++v;
  2012.     if (*s++ != v) {
  2013.         if (errs) {
  2014.         --errs;
  2015.         printf("(%ld)", s - orig);
  2016.         } else {
  2017.         printf("giveup");
  2018.         return(0);
  2019.         }
  2020.     }
  2021.     }
  2022.     return(errs == 255);
  2023. }
  2024.  
  2025.  
  2026. \Rogue\Monster\
  2027. else
  2028.   echo "will not over write util/test.c"
  2029. fi
  2030. if [ `wc -c util/test.c | awk '{printf $1}'` -ne 8363 ]
  2031. then
  2032. echo `wc -c util/test.c | awk '{print "Got " $1 ", Expected " 8363}'`
  2033. fi
  2034. if `test ! -s util/qtest.c`
  2035. then
  2036. echo "writing util/qtest.c"
  2037. cat > util/qtest.c << '\Rogue\Monster\'
  2038.  
  2039. /*
  2040.  *  QTEST.C
  2041.  */
  2042.  
  2043. #include <typedefs.h>
  2044. #include <stdio.h>
  2045.  
  2046. typedef struct Library LIB;
  2047.  
  2048. LIB *DMiscSupportBase;
  2049. long QHan;
  2050. long Count;
  2051. long EnErr;
  2052. long Error;
  2053.  
  2054. extern LIB *OpenLibrary();
  2055. extern TASK *FindTask();
  2056.  
  2057. handler(arg)
  2058. {
  2059.     printf("ARG: %ld ************\n", arg);
  2060. }
  2061.  
  2062. main()
  2063. {
  2064.     int i;
  2065.  
  2066.     DMiscSupportBase = OpenLibrary("dmiscsup.library", 0);
  2067.     if (!DMiscSupportBase) {
  2068.     puts("Unable to open library");
  2069.     exit(1);
  2070.     }
  2071.     puts("Q-TEST");
  2072.     QHan = OpenQInts();
  2073.     if (!QHan) {
  2074.     puts("Unable to alloc. q ints");
  2075.     CloseLibrary(DMiscSupportBase);
  2076.     exit(1);
  2077.     }
  2078.     printf("QHAn=  %08lx\n", QHan);
  2079.     puts("UnSetting NULL vector");
  2080.     SetQVector(QHan, NULL, SIGBREAKB_CTRL_E, 0, 0);
  2081.     puts("Setting ^D vector");
  2082.     SetQVector(QHan, handler, SIGBREAKB_CTRL_D, 30, -20);
  2083.     puts("UnSetting NULL vector");
  2084.     SetQVector(QHan, NULL, SIGBREAKB_CTRL_E, 0, 0);
  2085.     puts("Loop");
  2086.     for (i = 0; i < 100; ++i) {
  2087.     char oldpri = SetQPri(QHan, 127);
  2088.     EnErr = 1;
  2089.     printf("%ld  cnt = %ld  error = %ld (old=%ld) %08lx %08lx\n", i, Count, Error, oldpri,
  2090.         SetSignal(0,0), FindTask(NULL)->tc_SigExcept
  2091.     );
  2092.     EnErr = 0;
  2093.     SetQPri(QHan, oldpri);
  2094.     }
  2095.     puts("UnSetting NULL vector");
  2096.     SetQVector(QHan, NULL, SIGBREAKB_CTRL_E, 0, 0);
  2097.     printf("%ld  cnt = %ld  error = %ld\n", i, Count, Error);
  2098.     puts("closing");
  2099.     CloseQInts(QHan);
  2100.     puts("closelib");
  2101.     RemLibrary(DMiscSupportBase);
  2102.     CloseLibrary(DMiscSupportBase);
  2103. }
  2104.  
  2105.  
  2106. \Rogue\Monster\
  2107. else
  2108.   echo "will not over write util/qtest.c"
  2109. fi
  2110. if [ `wc -c util/qtest.c | awk '{printf $1}'` -ne 1448 ]
  2111. then
  2112. echo `wc -c util/qtest.c | awk '{print "Got " $1 ", Expected " 1448}'`
  2113. fi
  2114. if `test ! -s util/testarg.c`
  2115. then
  2116. echo "writing util/testarg.c"
  2117. cat > util/testarg.c << '\Rogue\Monster\'
  2118.  
  2119. /*
  2120.  *
  2121.  *
  2122.  */
  2123.  
  2124. #include <local/xmisc.h>
  2125.  
  2126. extern int Enable_Abort;
  2127.  
  2128. char *
  2129. getv(name)
  2130. char *name;
  2131. {
  2132.     printf("GET: '%s'\n", name);
  2133.     return("VAR");
  2134. }
  2135.  
  2136. freev(str)
  2137. char *str;
  2138. {
  2139.     printf("FREE: %s\n", str);
  2140. }
  2141.  
  2142. main(ac,av)
  2143. char *av[];
  2144. {
  2145.     char buf[256];
  2146.     char **Av;
  2147.     short Ac;
  2148.     long error;
  2149.  
  2150.     Enable_Abort = 0;
  2151.     openlibs(DRES_LIB);
  2152.  
  2153.     while (gets(buf)) {
  2154.     printf("Cmd: %s\n", buf);
  2155.     Ac = ParseCmd(buf, &Av, getv, freev, &error, NULL);
  2156.     printf("%08lx %ld\n", Av, Ac);
  2157.     if (error) {
  2158.         printf("ERROR!: %08lx\n", error);
  2159.     }
  2160.     if (Av) {
  2161.         short i;
  2162.         for (i = 0; i < Ac; ++i)
  2163.         printf("%2ld: (%ld) \"%s\"\n", i, Av[i][-1], Av[i]);
  2164.         puts("free");
  2165.         FreeParseCmd(Av);
  2166.         puts("ok");
  2167.     }
  2168.     }
  2169.  
  2170.     closelibs(-1);
  2171. }
  2172.  
  2173. \Rogue\Monster\
  2174. else
  2175.   echo "will not over write util/testarg.c"
  2176. fi
  2177. if [ `wc -c util/testarg.c | awk '{printf $1}'` -ne 743 ]
  2178. then
  2179. echo `wc -c util/testarg.c | awk '{print "Got " $1 ", Expected " 743}'`
  2180. fi
  2181. if `test ! -s util/x.c`
  2182. then
  2183. echo "writing util/x.c"
  2184. cat > util/x.c << '\Rogue\Monster\'
  2185.  
  2186.  
  2187. long Base;
  2188.  
  2189. main(ac,av)
  2190. char *av[];
  2191. {
  2192.     int ver = atoi(av[1]);
  2193.  
  2194.     Base = OpenLibrary("dres.library", ver);
  2195.     if (Base) {
  2196.     CloseLibrary(Base);
  2197.     puts("openned ok");
  2198.     } else {
  2199.     puts("open failed");
  2200.     }
  2201. }
  2202.  
  2203. \Rogue\Monster\
  2204. else
  2205.   echo "will not over write util/x.c"
  2206. fi
  2207. if [ `wc -c util/x.c | awk '{printf $1}'` -ne 215 ]
  2208. then
  2209. echo `wc -c util/x.c | awk '{print "Got " $1 ", Expected " 215}'`
  2210. fi
  2211. echo "Finished archive 1 of 3"
  2212. # if you want to concatenate archives, remove anything after this line
  2213. exit
  2214. -- 
  2215. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2216. Have five nice days.
  2217.